package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.RoleDto;
import com.zzyl.entity.Role;
import com.zzyl.entity.RoleResource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.RoleMapper;
import com.zzyl.mapper.RoleResourceMapper;
import com.zzyl.mapper.UserRoleMapper;
import com.zzyl.service.RoleService;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.vo.RoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 角色业务接口实现类
 */

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleResourceMapper roleResourceMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    /**
     * 分页条件查询
     * @param pageNum 页码
     * @param pageSize 本页条数
     * @param roleName 角色名
     */
    @Override
    public PageResponse<RoleVo> getByPage(Integer pageNum, Integer pageSize, String roleName) {
        //分页插件
        PageHelper.startPage(pageNum, pageSize);
        //封装
        Page<RoleVo> result = roleMapper.selectPage(roleName);
        //返回
        return PageResponse.of(result,RoleVo.class);
    }

    /**
     * 新增角色
     * @param roleDto 新增数据信息
     */
    @Override
    public void addRole(RoleDto roleDto) {
        //更换映射
        Role role = BeanUtil.copyProperties(roleDto, Role.class);
        //角色名不可为空
        if (role.getRoleName().isEmpty()){
            throw new BaseException(BasicEnum.INSERT_ROLE_FAIL_NAME_NULL);
        }
        //角色名不可重复
        Long count = roleMapper.selectByName(role.getRoleName());
        if (count > 0){
            throw new BaseException(BasicEnum.INSERT_ROLE_FAIL_NAME_REPEAT);
        }
        //新增角色
        roleMapper.insert(role);
    }

    /**
     * 根据角色ID查询资源数据
     * @param roleId 角色ID
     */
    @Override
    public List<String> getResourceIdByRoleId(Long roleId) {
        return roleResourceMapper.selectResourceIdByRoleId(roleId);
    }

    /**
     * 修改角色
     * @param roleDto 修改信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateRole(RoleDto roleDto) {
        //更换映射
        Role role = BeanUtil.copyProperties(roleDto, Role.class);
        //角色绑定用户不可禁用
        Long user = userRoleMapper.selectUserByRole(role);
        if (user > 0 && role.getDataState().equals("1")){
            throw new BaseException(BasicEnum.UPDATE_ROLE_STATUS_NOUSE_FAIL_HAS_USER);
        }
        //角色名不可重复【除自身名字外】
        Long roleName = roleMapper.selectByNameWithoutSelf(role);
        if (roleName > 0){
            throw new BaseException(BasicEnum.UPDATE_ROLE_FAIL_REPEAT_NAME);
        }
        //若修改菜单资源
        if (ObjectUtil.isNotEmpty(roleDto.getCheckedResourceNos())) {
            //删除所有原资源数据
            roleResourceMapper.delectAllForUpdate(role.getId());
            //批量添加资源数据
            for (String checkedResourceNo : roleDto.getCheckedResourceNos()) {
                RoleResource roleResource = RoleResource.builder()
                        .resourceNo(checkedResourceNo)
                        .roleId(role.getId())
                        .dataState(SuperConstant.DATA_STATE_0)
                        .build();
                roleResourceMapper.insert(roleResource);
            }
        }
        //修改角色
        roleMapper.updateByPrimaryKeySelective(role);
    }

    /**
     * 删除角色
     * @param roleId 角色ID
     */
    @Override
    public void remove(Long roleId) {
        //启用状态下无法删除
        String status = roleMapper.getStatus(roleId);
        if (status.equals("0")){
            throw new BaseException(BasicEnum.DELETE_ROLE_FAIL_INUSE);
        }
        //删除角色
        roleMapper.deleteByPrimaryKey(roleId);
        //删除角色绑定的资源（关联信息）
        roleResourceMapper.delectAllForUpdate(roleId);
    }

    /**
     * 角色下拉框
     */
    @Override
    public List<RoleVo> getInitRoles() {
        List<RoleVo> result = roleMapper.selectInitRoles();
        return result;
    }


}
